<template>
  <div class="tree-container" :style="{ height: chartHeight + 'px', minHeight: '800px' }">
    <div ref="chart" class="chart" @click="handleChartClick"></div>
    <div class="detail-panel" :class="{ 'show': drawerVisible, 'expanded': isExpanded }">
      <div class="detail-header">
        <div class="header-left">
          <span v-if="!isExpanded" class="expand-btn" @click="handleExpand">展开</span>
          <span v-else class="expand-btn" @click="handleCollapse">收起</span>
        </div>
        <div class="header-right">
          <span class="close-btn" @click="handleClose">×</span>
        </div>
      </div>
      <div class="detail-body" v-loading="loading" element-loading-text="加载中..." element-loading-background="rgba(255, 255, 255, 0.7)">
        <div v-if="hasNoDetailData" class="no-data-mask">
          <img src="../KnowledgeGraphItem/images/nodata.gif" class="no-data-img">
          <div class="no-data-text">此节点无详情数据</div>
        </div>
        <template v-else>
          <div class="node-info">
            <span class="attr-tag attr-tag1">属性名</span>
            <h3>{{ nodeDetail.nodeName }}</h3>
          </div>
          <div class="node-info">
            <span class="attr-tag attr-tag3">别名</span>
            <h3>{{ nodeDetail.nodeAlias }}</h3>
          </div>
          <div class="node-info">
            <span class="attr-tag attr-tag2">属性</span>
            <h3>{{ nodeDetail.nodeAttributes }}</h3>
          </div>
          <div class="detail-content" >
            <span class="attr-tag attr-tag4">描述</span>
            <p>{{ nodeDetail.nodeDescription }}</p>
          </div>
          <div class="detail-content">
            <span class="attr-tag attr-tag5">物理意义</span>
            <p>{{ nodeDetail.nodePhysicalSignificance }}</p>
          </div>
          <div class="detail-content">
            <span class="attr-tag attr-tag6">化学意义</span>
            <p>{{ nodeDetail.nodeChemicalSignificance }}</p>
          </div>
          <div class="node-info">
            <span class="attr-tag attr-tag7">数学依赖性</span>
            <h3>{{ nodeDetail.nodeMathematicalDependency }}</h3>
          </div>
      <div class="node-info">
            <span class="attr-tag attr-tag8">实验依据</span>
            <h3>{{ nodeDetail.nodeExperimentalBasis }}</h3>
          </div>
          <div class="detail-content">
            <span class="attr-tag attr-tag9">历史背景</span>
            <p>{{ nodeDetail.nodeHistoricalBackground }}</p>
          </div>
          <div class="detail-content">
            <span class="attr-tag attr-tag10">典型案例</span>
            <p>{{ nodeDetail.nodeTypicalCases }}</p>
      </div>
      <div class="detail-content">
            <span class="attr-tag attr-tag11">学科前沿</span>
            <p>{{ nodeDetail.nodeFrontier }}</p>
          </div>
        </template>
      </div>
    </div>
  </div>
</template>
  
<script>
import * as echarts from 'echarts';
import wuliIcon from './images/wuli3.png';
import knowledgeGraph from '@/api/knowledgeGraph'
export default {
  name: 'TreeGraph',
  props: {
    treeData: {
      type: Object,
      default: () => ({})
    }
  },
  data() {
    return {
      chart: null,
      processedData: null,
      drawerVisible: false,
      isExpanded: false,
      nodeDetail:{},//节点详情数据
      selectedNode: {
        name: '',
        description: ''
      },
      chartHeight: 700,
      baseItemHeight: 150,
      loading: false
    };
  },
  watch: {
    treeData: {
      handler(newVal) {
        if (newVal && Object.keys(newVal).length > 0) {
          this.processedData = this.processData(newVal);
          if (!this.chart) {
            this.$nextTick(() => {
              this.initChart();
            });
          } else {
            this.chart.setOption({
              series: [{
                data: [this.processedData]
              }]
            });
            this.$nextTick(() => {
              this.calculateChartHeight();
            });
          }
        }
      },
      immediate: true
    }
  },
  mounted() {
      document.addEventListener('click', this.handleOutsideClick);
    window.addEventListener('resize', this.handleResize);
  },
  beforeDestroy() {
    window.removeEventListener('resize', this.handleResize);
    document.removeEventListener('click', this.handleOutsideClick);
    if (this.chart) {
      this.chart.dispose();
    }
  },
  methods: {
    getNodeColor(attrs, level, parentColor) {
      
      const baseColors = {
        '物理化学': '#2a2a73',  // 根节点颜色
        '绪论': '#ff4e4e',            
        '热力学第一定律': '#ff3e8a',  
        '热力学第二定律': '#604ffd',  
        '多相分系统热力学及其在溶液中的应用': '#3557ff', 
        '相平衡': '#d9b611',          
        '化学平衡': '#00a167',        
        '统计热力学基础': '#00a82a',  
        '电解质溶液': '#ff4e4e',     
        '可逆电池的电动势及其应用': '#884898', 
        '电解与极化作用': '#4d5aaf', 
        '化学动力学基础': '#44cef6',   
        '表面物理化学': '#00a3af',     
        '胶体分散系统和大分子溶液': '#ffa400' 
      };

      let resultColor;

      // 如果是第一级节点，使用默认颜色
      if (level === 1) {
        resultColor = baseColors['物理化学'];
      }
      // 如果是第二级节点，使用对应的基础颜色
      else if (level === 2) {
        resultColor = baseColors[attrs] || '#2a2a73';
      }
      // 如果是更深层级的节点，使用父节点颜色的浅色版本
      else if (level > 2 && parentColor) {
        let r, g, b;
        
        // 检查父节点颜色是否为 rgb 格式
        if (parentColor.startsWith('rgb')) {
          const matches = parentColor.match(/rgb\((\d+),\s*(\d+),\s*(\d+)\)/);
          if (matches) {
            r = parseInt(matches[1]);
            g = parseInt(matches[2]);
            b = parseInt(matches[3]);
          }
        } else {
          // 处理十六进制颜色
          const hex = parentColor.replace('#', '');
          r = parseInt(hex.substring(0, 2), 16);
          g = parseInt(hex.substring(2, 4), 16);
          b = parseInt(hex.substring(4, 6), 16);
        }
        
        // 确保 r, g, b 都是有效数字
        if (!isNaN(r) && !isNaN(g) && !isNaN(b)) {
          // 调整颜色变浅的程度
          const factor = level === 3 ? 0.15 : 0.3; // 减小变浅的程度
          const newR = Math.min(r + (255 - r) * factor, 255);
          const newG = Math.min(g + (255 - g) * factor, 255);
          const newB = Math.min(b + (255 - b) * factor, 255);
          resultColor = `rgb(${Math.round(newR)}, ${Math.round(newG)}, ${Math.round(newB)})`;
        } else {
          resultColor = '#2a2a73';  // 如果颜色解析失败，使用默认颜色
        }
      }
      else {
        resultColor = '#2a2a73';
      }

      console.log('计算结果:', {
        nodeName: attrs,
        level: level,
        parentColor: parentColor,
        resultColor: resultColor
      });

      return resultColor;
    },

    processData(data, level = 1, parentColor = null) {
      const processNode = (node, currentLevel, pColor) => {
        const nodeName = node.label || node.name || node.nodeName;
        
        // 计算当前节点的颜色
        const currentColor = this.getNodeColor(nodeName, currentLevel, pColor);
        console.log('处理节点:', {
          nodeName: nodeName,
          level: currentLevel,
          parentColor: pColor,
          currentColor: currentColor
        });
        
        const newNode = {
          id: node.id,
          name: nodeName,
          level: currentLevel,
          description: node.description || this.generateMockDescription(nodeName),
          itemStyle: {
            color: currentColor
          }
        };

        if (node.children && node.children.length > 0) {
          // 将当前节点的颜色作为父节点颜色传递给子节点
          newNode.children = node.children.map(child => 
            processNode(child, currentLevel + 1, currentColor)
          );
        }

        return newNode;
      };

      return processNode(data, level, parentColor);
    },

    generateMockDescription(nodeName) {
      return `这是关于 ${nodeName} 的详细描述。包含了该知识点的核心概念、应用场景以及相关的理论基础。这些内容可以帮助更好地理解和掌握该知识点。`;
    },

    calculateChartHeight() {
      if (!this.chart || !this.chart._chartsViews || !this.chart._chartsViews[0] || !this.chart._chartsViews[0]._data) {
        return;
      }
      
      try {
        const eleArr = Array.from(new Set(this.chart._chartsViews[0]._data._graphicEls));
        const visibleNodes = eleArr.filter(el => el && el.ignore === false);
        const currentHeight = this.baseItemHeight * (visibleNodes.length || 1);
        const newHeight = Math.max(currentHeight, 800);
        
        this.chartHeight = newHeight;
        this.chart.resize({
          height: newHeight
        });
      } catch (error) {
        console.error('计算图表高度时出错:', error);
      }
    },

    initChart() {
      const chartDom = this.$refs.chart;
      if (!chartDom) return;

      this.chart = echarts.init(chartDom);
      
      const option = {
        backgroundColor: '#f5f6fb',
        tooltip: {
          trigger: 'item',
          triggerOn: 'mousemove'
        },
        series: [
          {
            type: 'tree',
            data: [this.processedData],
            left: '5%',
            right: '35%',
            top: '0%',
            bottom: '50%',
            orient: 'LR',
            symbol: (value, params) => {
              if (!params || !params.data || !params.data.name) {
                return 'rect';
              }
              const width = Math.max(params.data.name.length * 14 + 30, 100);
              const height = 35;
              const radius = 10;
              
              let path = `M${radius},0 L${width-radius},0 Q${width},0 ${width},${radius} L${width},${height-radius} Q${width},${height} ${width-radius},${height} L${radius},${height} Q0,${height} 0,${height-radius} L0,${radius} Q0,0 ${radius},0`;
              
              if (params.data.children && params.data.children.length) {
                const btnSize = 8;
                const btnX = width + btnSize/2 + 5;
                const btnY = height/2;
                
                path += ` M${btnX},${btnY} m${-btnSize/2},0 a${btnSize/2},${btnSize/2} 0 1,0 ${btnSize},0 a${btnSize/2},${btnSize/2} 0 1,0 ${-btnSize},0`;
                
                const symbolSize = 4;
                if (params.data.collapsed !== false) {
                  path += ` M${btnX-symbolSize},${btnY} h${symbolSize*2} M${btnX},${btnY-symbolSize} v${symbolSize*2}`;
                } else {
                  path += ` M${btnX-symbolSize},${btnY} h${symbolSize*2}`;
                }
              }
              
              return 'path://' + path;
            },
            symbolSize: (value, params) => {
              if (!params || !params.data || !params.data.name) {
                return [100, 35];
              }
              const tempSpan = document.createElement('span');
              tempSpan.style.visibility = 'hidden';
              tempSpan.style.fontSize = '14px';
              tempSpan.innerHTML = params.data.name;
              document.body.appendChild(tempSpan);
              const width = tempSpan.offsetWidth;
              document.body.removeChild(tempSpan);
              const btnWidth = (params.data.children && params.data.children.length) ? 25 : 0;
              return [Math.max(width + 80, 140) + btnWidth, 35];
            },
            roam: true,
            initialTreeDepth: 1,
            itemStyle: {
              borderWidth: 0,
              emphasis: {
                disabled: false,
                borderWidth: 2,
                borderColor: '#c0b6ff'
              }
            },
            lineStyle: {
              color: {
                type: 'linear',
                x: 0,
                y: 0,
                x2: 1,
                y2: 0,
                colorStops: [{
                  offset: 0,
                  color: 'rgb(238, 54, 218)'
                }, {
                  offset: 1,
                  color: 'rgb(139, 250, 252)'
                }]
              },
              width: 1.5,
              curveness: 0.5
            },
            layout: 'orthogonal',
            edgeShape: 'polyline',
            edgeForkPosition: '50%',
            label: {
              position: 'inside',
              color: '#fff',
              fontSize: 12,
              formatter: (params) => {
                if (params.data.level === 2) {
                  return [
                    '{icon|}  {text|' + (params.name || '') + '}'
                  ].join('');
                } else {
                  return params.name || '';
                }
              },
              rich: {
                icon: {
                  height: 30,
                  width: 30,
                  align: 'center',
                  verticalAlign: 'middle',
                  backgroundColor: {
                    image: wuliIcon
                  }
                },
                text: {
                  align: 'left',
                  verticalAlign: 'middle',
                  padding: [0, 0, 0, 5]
                }
              },
              align: 'center',
              verticalAlign: 'middle',
              padding: [0, 0, 0, -40]
            },
            emphasis: {
              disabled: true
            },
            leaves: {
              label: {
                position: 'inside',
                color: '#fff'
              },
              itemStyle: {
                emphasis: {
                  disabled: false,
                  borderWidth: 2,
                  borderColor: '#c0b6ff'
                }
              }
            },
            expandAndCollapse: true,
            animationDuration: 500,
            animationDurationUpdate: 500,
            nodeGap: 100,
            layerPadding: 120
          }
        ]
      };

      this.chart.on('click', this.handleNodeClick);

      this.chart.setOption(option);
      this.calculateChartHeight();
    },
    
    handleResize() {
      if (this.chart) {
        this.chart.resize();
        this.calculateChartHeight();
      }
    },

    handleExpand() {
      this.isExpanded = true;
    },

    handleCollapse() {
      this.isExpanded = false;
    },

    handleClose() {
      this.drawerVisible = false;
      this.isExpanded = false;
    },

    handleOutsideClick(event) {
      if (this.drawerVisible) {
        const panel = document.querySelector('.detail-panel');
        if (panel && !panel.contains(event.target)) {
          this.handleClose();
        }
      }
    },

    handleChartClick(event) {
      event.stopPropagation();
    },

    async handleNodeClick(params) {
      if (params.data && params.data.children) {
        const btnSize = 10;
        const width = params.data.symbolSize ? params.data.symbolSize[0] : 120;
        const height = 40;
        const btnX = width + btnSize/2 + 5;
        const btnY = height/2;
        
        const clickX = params.event.offsetX - params.event.target.x;
        const clickY = params.event.offsetY - params.event.target.y;
        
        if (Math.abs(clickX - btnX) <= btnSize && Math.abs(clickY - btnY) <= btnSize) {
          params.data.collapsed = !params.data.collapsed;
          this.chart.setOption(this.chart.getOption());
          setTimeout(() => {
            this.calculateChartHeight();
          }, 500);
          return;
        }
      }

      if (params.data && params.data.level >= 2) {
        try {
          this.loading = true;
          this.drawerVisible = true;
          this.isExpanded = false;
          
          const response = await knowledgeGraph.getKnowledgeGraphDetail(params.data.id);
          // console.log('知识图谱节点详情数据：', response);
          this.nodeDetail = response.data;
          this.selectedNode = {
            name: params.data.name,
            description: params.data.description || this.generateMockDescription(params.data.name)
          };
        } catch (error) {
          console.error('获取知识图谱节点详情失败：', error);
          this.$message.error('获取节点详情失败');
        } finally {
          this.loading = false;
        }
      }
    }
  },
  computed: {
    hasNoDetailData() {
      const detail = this.nodeDetail;
      // 检查除了 nodeName 之外的其他字段是否都为空
      return !detail.nodeAlias && 
             !detail.nodeAttributes && 
             !detail.nodeDescription && 
             !detail.nodePhysicalSignificance && 
             !detail.nodeChemicalSignificance && 
             !detail.nodeMathematicalDependency && 
             !detail.nodeExperimentalBasis && 
             !detail.nodeHistoricalBackground && 
             !detail.nodeTypicalCases && 
             !detail.nodeFrontier;
    }
  }
};
</script>
  
<style lang="scss" scoped>
.tree-container {
  width: 100%;
  background-color: #f5f6fb;
  position: relative;
  transition: height 0.3s ease;
    
  .chart {
    width: 100%;
    height: 100%;
  }
}

.detail-panel {
  position: absolute;
  right: -420px;
  width: 400px;
  height: 785px;
  z-index: 9999;
  top: 10px;
  background-color: rgba(255, 255, 255, 0.1);
  backdrop-filter: blur(13px);
  border: 1px solid rgba(255, 255, 255, 0.18);
  box-shadow: rgba(142, 142, 142, 0.19) 0px 6px 15px 0px;
  border-radius: 15px;
  color: rgba(255, 255, 255, 0.3);
  transition: all 0.3s ease;
  display: flex;
  flex-direction: column;
  opacity: 0;
  pointer-events: none;
  
  &.show {
    right: 10px;
    opacity: 1;
    pointer-events: auto;
  }
  
  &.expanded {
    width: 800px;
  }

  .detail-header {
    display: flex;
    justify-content: space-between;
    align-items: center;
    padding: 12px 16px;
    border-bottom: 1px solid #f0f0f0;

    .header-left {
      .expand-btn {
        cursor: pointer;
        color: #a0a0a1;
        font-size: 14px;
        
        &:hover {
          color: #40a9ff;
        }
      }
    }

    .header-right {
      .close-btn {
        cursor: pointer;
        color: #999;
        font-size: 20px;
        line-height: 1;
        padding: 4px 8px;
        
        &:hover {
          color: #666;
        }
      }
    }
  }

  .node-info {
    padding: 16px;
    border-bottom: 1px solid #f0f0f0;

    .attr-tag {
      display: inline-block;
      padding: 1px 6px;
      border-radius: 5px;
      font-size: 14px;
      margin-bottom: 8px;
    }

    h3 {
      margin: 0;
      font-size: 16px;
      color: #333;
      font-weight: bold;
    }
  }

  .detail-content {
    flex: 1;
    padding: 16px;
    position: relative;
    border-bottom: 1px solid #f0f0f0;
    .attr-tag {
      display: inline-block;
      padding: 1px 6px;
      border-radius: 5px;
      font-size: 14px;
      margin-bottom: 8px;
    }
    &::-webkit-scrollbar {
      width: 6px;
    }

    &::-webkit-scrollbar-thumb {
      background: #d9d9d9;
      border-radius: 3px;
    }

    &::-webkit-scrollbar-track {
      background: #f5f5f5;
    }

    p {
      margin: 0;
      padding: 16px;
      background: #e1e2e3;
      border-radius: 8px;
      color: #333;
      line-height: 1.8;
      font-size: 14px;
    }
  }
}
.detail-body{
  width: 100%;
  height: 100%;
  overflow-y: auto;
  background-color: transparent;
  position: relative;
}

.no-data-mask {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  justify-content: flex-start;
  align-items: center;
  z-index: 1;

  .no-data-text {
    font-size: 16px;
    color: #666;
    padding: 5px 30px;
    background-color: #f5f5f5;
    border-radius: 5px;
    box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
  }
}
.no-data-img{
  width: 250px;
  height: 250px;
}
.attr-tag1{
      background: #b0a4e3;
      color: #f0f0f4;

}
.attr-tag2{
      background: #ffb61e;
      color: #f0f0f4;
}
.attr-tag3{
  background: #def3ec;
  color: #00ca8e;
}
.attr-tag4{
  background: #eacd76;
  color: #f0f0f4;
}
.attr-tag5{
  background: #00e09e;
  color: #f0f0f4;
}
.attr-tag6{
  background: #68be8d;
  color: #f0f0f4;
}
.attr-tag7{
  background: #89c3eb;
  color: #f0f0f4;
}
.attr-tag8{
  background: #cc7eb1;
  color: #f0f0f4;
}
.attr-tag9{
  background: #a6a5c4;
  color: #f0f0f4;
}
.attr-tag10{
  background: #59b9c6;
  color: #f0f0f4;
}
.attr-tag11{
  background: #88cb7f;
  color: #f0f0f4;
}
</style>